﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace landlord2lib
{
    public abstract class CardGroup : IComparable<CardGroup>
    {
        protected Card[] m_cards;
        protected bool m_isValid;

        public abstract bool IsValid();

        public abstract int CompareTo(CardGroup other);

        protected Card[] Cards
        {
            get
            {
                return m_cards;
            }
        }

        public static CardGroup AssignCardGroup(Card[] cards)
        {
            CardGroupBoom boom = new CardGroupBoom(cards);
            if (boom.IsValid()) return boom;

            CardGroupButterfly butterfly = new CardGroupButterfly(cards);
            if (butterfly.IsValid()) return butterfly;

            CardGroupProgressTriple pt = new CardGroupProgressTriple(cards);
            if (pt.IsValid()) return pt;

            CardGroupProgressPair pp = new CardGroupProgressPair(cards);
            if (pp.IsValid()) return pp;

            CardGroupGourd gourd = new CardGroupGourd(cards);
            if (gourd.IsValid()) return gourd;

            CardGroupTriple triple = new CardGroupTriple(cards);
            if (triple.IsValid()) return triple;

            CardGroupPair pair = new CardGroupPair(cards);
            if (pair.IsValid()) return pair;

            CardGroupSingle single = new CardGroupSingle(cards);
            if (single.IsValid()) return single;

            return null;
        }

        public static HintCardCollection Hint(Card[] handCards, CardGroup lastGroup)
        {
            HintCardCollection result = null;
            if (lastGroup is CardGroupSingle) result = CardGroupSingle.Hint(handCards, (CardGroupSingle)lastGroup);
            else if (lastGroup is CardGroupPair) result = CardGroupPair.Hint(handCards, (CardGroupPair)lastGroup);
            else if (lastGroup is CardGroupTriple) result = CardGroupTriple.Hint(handCards, (CardGroupTriple)lastGroup);
            else if (lastGroup is CardGroupGourd) result = CardGroupGourd.Hint(handCards, (CardGroupGourd)lastGroup);
            else if (lastGroup is CardGroupProgressPair) result = CardGroupProgressPair.Hint(handCards, (CardGroupProgressPair)lastGroup);
            else if (lastGroup is CardGroupProgressTriple) result = CardGroupProgressTriple.Hint(handCards, (CardGroupProgressTriple)lastGroup);
            else if (lastGroup is CardGroupBoom) result = CardGroupBoom.Hint(handCards, (CardGroupBoom)lastGroup);
#if !DEBUG
            if (!(lastGroup is CardGroupBoom))
            {
                if (result != null) result = result.Merge(CardGroupBoom.Hint(handCards, null));
                else result = CardGroupBoom.Hint(handCards, null);
            }
#endif
            return result;
        }
    }
}
